package com.dau.common.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.thread.ConcurrencyTester;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * Id生成工具
 *
 * @author hyin
 */
public class IdTool {

    /**
     * 生成32位字符串自增ID
     *
     * @return 32位数字组成的字符串
     */
    public static String nextNumberStr() {
        return nextNumberStr32ByDate();
    }

    /**
     * 生成32位字符串自增ID.
     * <p>
     * 结构：前12位由日期构成，拼接常量0，再拼接19位snowflake.
     *
     * @return 32位数字组成的字符串
     */
    public static String nextNumberStr32ByDate() {
        return DateUtil.format(new Date(), "yyyyMMddHHmm0") + IdWorker.getIdStr();
    }

    /**
     * 生成32位字符串自增ID.
     * <p>
     * 结构：前19位snowflake，拼接13位timestamp.
     *
     * @return 32位数字组成的字符串
     */
    public static String nextNumberStr32ByTimestamp() {
        return IdWorker.getIdStr() + SystemClock.now();
    }

    /**
     * 生成36位字符串自增ID
     * <p>
     * 结构：前17位yyyyMMddHHmmssSSS，拼接19位snowflake.
     *
     * @return 36位数组组成的字符串
     */
    public static String nextNumberStr36ByDate() {
        return IdWorker.getTimeId();
    }

    /**
     * 生成28位字符串自增ID
     * <p>
     * 结构：4位前缀 + 17位yyyyMMddHHmmssSSS + snowflake后7位
     *
     * @param prefix4 长度4位字符串，不能为null或者"null"
     * @return 28位增长字符串
     */
    public static String nextNumberStr28ByPrefix4(String prefix4) {
        if (StrUtil.isBlankOrUndefined(prefix4)) {
            throw new IllegalArgumentException("生成28位字符串自增ID参数错误:" + prefix4);
        }
        return prefix4 + IdWorker.getMillisecond() + StrUtil.subSufByLength(IdWorker.getIdStr(), prefix4.length()+1);
    }

    public static void main(String[] args) throws IOException {
        final ConcurrencyTester tester = new ConcurrencyTester(10);
        Set<String> rs = new HashSet<>();
        System.out.println("并发生成数字自增ID：");
        tester.test(() -> {
            final String id = nextNumberStr32ByDate();
//            final String id = nextNumberStr32ByTimestamp();
//            final String id = nextNumberStr28ByPrefix4("STORE");
//            final String id =supplement(); luck Draw prize  cheat
            System.out.println(id);
//            rs.add(id);
        });
        System.out.println("结果集：");
        System.out.println(rs.size());
        tester.close();
    }

}
